package com.zmht.beike.core;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Example;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.zmht.beike.model.PageModel;



public class BaseDAOImpl extends org.springframework.orm.hibernate3.support.HibernateDaoSupport implements IBaseDAO {

	/**
	 * @author fengbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#deleteObj(java.lang.Object)
	 */
	public boolean deleteObj(Object obj) {
		try{
		this.getHibernateTemplate().delete(obj);
		}catch(Exception ex){
			return false;
		}
		return true;
	}
	/**
	 * @author fengbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findAllObj(java.lang.Object)
	 */
	public List findAllObj(Object obj) {
		List list = this.getHibernateTemplate().findByExample(obj);
		return list;
	}
	/**
	 * @author fengbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByHQLObj(java.lang.String)
	 */
	public List findByHQLObj(String htl) {
		List list = this.getHibernateTemplate().find(htl);
		return list;
	}
	/**
	 * @author fengbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#saveObj(java.lang.Object)
	 */
	public Object saveObj(Object obj) {
		try{
		return this.getHibernateTemplate().save(obj);
		}catch(Exception ex){
			ex.printStackTrace();
			return null;
		}
		
	}
	
	public boolean updateObj(Object obj) {
		try{
		this.getHibernateTemplate().update(obj);
		}catch(Exception ex){
			return false;
		}
		return true;
	}
	/**
	 * @author fengbo
	 * 请查看父接口说明
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findById(java.lang.Class, java.io.Serializable)
	 */
	public Object findById(Class c, Serializable s) {
	//	System.out.println("is = "+s);
			return this.getHibernateTemplate().get(c, s);	
	}
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPage(java.lang.String, int, int)
	 */
	public List findByPage(final String hql,final int offset,final int pageSize){
	   List list=this.getHibernateTemplate().executeFind(new HibernateCallback()
	   {
	    public Object doInHibernate(Session session)
	      throws HibernateException, SQLException {
	     List result=session.createQuery(hql).setFirstResult(offset).setMaxResults(pageSize).list();
	     return result;
	    }
	   }
	   );
	   return list;
	}
	
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPage(java.lang.String, java.lang.String, int, int)
	 */
	public List findByPage(final String hql,final String value,final int offset,final int pageSize)	{
	   List list=this.getHibernateTemplate().executeFind(new HibernateCallback(){
	    public Object doInHibernate(Session session) throws HibernateException, SQLException {
	     List result=session.createQuery(hql).setParameter(0,value).setFirstResult(offset).setMaxResults(pageSize).list();
	     return result;
	    }
	   }
	   );
	   return list;
	}
	
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPage(java.lang.String, java.lang.Object[], int, int)
	 */
	public List findByPage(final String hql,final Object[] values,final int offset,final int pageSize){
	   List list=this.getHibernateTemplate().executeFind(new HibernateCallback(){
	    public Object doInHibernate(Session session) throws HibernateException, SQLException {
	     Query query=session.createQuery(hql);
	     for(int i=0;i<values.length;i++)
	     {
	      query.setParameter(i,values[i]);
	     }
	     List result=query.setFirstResult(offset).setMaxResults(pageSize).list();
	     return result;
	    }
	   }
	   );
	   return list;
	}
	/*根据条件查询 记录总数
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findTotalCount(java.lang.Class, java.lang.Object)
	 */
	public Integer findTotalCount(Class c, Object condition) {
		try{
		List list = this.getSession().createCriteria(c).add(Example.create(condition)).list();
		return list.size();
		}catch(Exception e){
			return 0;
		}
		
	}
	
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPageAmount(java.lang.String)
	 */
	public int findByPageAmount(final String hql) {
		/*List list=this.getHibernateTemplate().executeFind(new HibernateCallback()
		   {
		    public Object doInHibernate(Session session)
		      throws HibernateException, SQLException {
		     List result=session.createQuery(hql).list();
		     return result;
		    }
		   }
		   );
		return list.size();*/
		try {
		    Integer amount = new Integer(0);
		    int sql_from = hql.indexOf("from");
		    int sql_orderby = hql.indexOf("order by");// 为了改进
		    String countStr = "";

		    if (sql_orderby > 0) {
			countStr = "select count(*) "
				+ hql.substring(sql_from, sql_orderby);
		    } else
			countStr = "select count(*) " + hql.substring(sql_from);

		    Query query = getSession().createQuery(countStr);
		    List temp = query.list();
		    if (!temp.isEmpty()) {
			amount = new Integer(temp.get(0).toString());
		    } else
			return 0;
		    return amount.intValue();
		} catch (Exception e) {
			return 0;
		}
	}
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPageAmount(java.lang.String, java.lang.String)
	 */
	public int findByPageAmount(final String hql,final String value) {
		List list=this.getHibernateTemplate().executeFind(new HibernateCallback(){
		    public Object doInHibernate(Session session) throws HibernateException, SQLException {
		     List result=session.createQuery(hql).setParameter(0,value).list();
		     return result;
		    }
		   }
		   );
		return list.size();
	}
	
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPageAmount(java.lang.String, java.lang.Object[])
	 */
	public int findByPageAmount(final String hql,final Object[] values) {
		List list=this.getHibernateTemplate().executeFind(new HibernateCallback(){
		    public Object doInHibernate(Session session) throws HibernateException, SQLException {
		     Query query=session.createQuery(hql);
		     for(int i=0;i<values.length;i++)
		     {
		      query.setParameter(i,values[i]);
		     }
		     List result=query.list();
		     return result;
		    }
		   }
		   );
		return list.size();
	}
	
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findBySql(java.lang.String)
	 */
	public List findBySql(String sql) {
		return this.getSession().createSQLQuery(sql).list();
	}
	
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findBySql(java.lang.String, int, int)
	 */
	public List findBySql(String sql,int offset,int pageSize) {
		return this.getSession().createSQLQuery(sql).setFirstResult(offset).setMaxResults(pageSize).list();
	}
	
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findAmountBySql(java.lang.String)
	 */
	public int findAmountBySql(String sql) {
		/*try {
		    Integer amount = new Integer(0);
		    int sql_from = sql.indexOf("from");
		    int sql_orderby = sql.indexOf("order by");// 为了改进
		    String countStr = "";

		    if (sql_orderby > 0) {
			countStr = "select count(*) "
				+ sql.substring(sql_from, sql_orderby);
		    } else
			countStr = "select count(*) " + sql.substring(sql_from);

		    Query query = getSession().createQuery(countStr);
		    List temp = query.list();
		    if (!temp.isEmpty()) {
			amount = new Integer(temp.get(0).toString());
		    } else
			return 0;
		    return amount.intValue();
		} catch (Exception e) {
			return 0;
		}*/
		return this.getSession().createSQLQuery(sql).list().size();
	}

	/**
	 * @author wangbo (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPage(java.lang.String, int,
	 *      int)
	 */
	public PageModel findByPageReturnPageModel(final String hql, final int currPage,
			final int pageSize) {
		List resultList = this.getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						List result = session.createQuery(hql).setFirstResult(
								(currPage-1)*pageSize).setMaxResults(pageSize).list();
						return result;
					}
				});
		
		PageModel pageModel = new PageModel();
		int resultAmount = findByPageAmount(getPageAmountHQLReturnPageModel(hql));
		pageModel.setResultAmount(resultAmount);
		int pageAmount = (resultAmount+pageSize-1)/pageSize;
		pageModel.setPageAmount(pageAmount==0?1:pageAmount);
		pageModel.setResultList(resultList);
		
		return pageModel;
	}

	/**
	 * @author wangbo (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPage(java.lang.String,
	 *      java.lang.String, int, int)
	 */
	public PageModel findByPageReturnPageModel(final String hql, final String value,
			final int currPage, final int pageSize) {
		List resultList = this.getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						List result = session.createQuery(hql).setParameter(0,
								value).setFirstResult((currPage-1)*pageSize).setMaxResults(
								pageSize).list();
						return result;
					}
				});
		
		PageModel pageModel = new PageModel();
		int resultAmount = findByPageAmount(getPageAmountHQLReturnPageModel(hql), value);
		pageModel.setResultAmount(resultAmount);
		int pageAmount = (resultAmount+pageSize-1)/pageSize;
		pageModel.setPageAmount(pageAmount==0?1:pageAmount);
		pageModel.setResultList(resultList);
		
		return pageModel;
	}

	/**
	 * @author wangbo (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPage(java.lang.String,
	 *      java.lang.Object[], int, int)
	 */
	public PageModel findByPageReturnPageModel(final String hql, final Object[] values,
			final int currPage, final int pageSize) {
		List resultList = this.getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						for (int i = 0; i < values.length; i++) {
							query.setParameter(i, values[i]);
						}
						List result = query.setFirstResult((currPage-1)*pageSize)
								.setMaxResults(pageSize).list();
						return result;
					}
				});
		
		PageModel pageModel = new PageModel();
		int resultAmount = findByPageAmount(getPageAmountHQLReturnPageModel(hql), values);
		pageModel.setResultAmount(resultAmount);
		int pageAmount = (resultAmount+pageSize-1)/pageSize;
		pageModel.setPageAmount(pageAmount==0?1:pageAmount);
		pageModel.setResultList(resultList);
		
		return pageModel;
	}

	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.cader.ehs.core.dao.IBaseDAO#getPageAmountHQL(java.lang.String)
	 */
	private String getPageAmountHQLReturnPageModel(String HQL) {
		int FROM = HQL.indexOf("from");// from 下标
		int ORDER_BY = HQL.indexOf("order by");// order by 下标
		StringBuffer countStr = new StringBuffer("select count(*) ");

		// 拼接hql
		if (ORDER_BY > 0) {
			countStr.append(HQL.substring(FROM, ORDER_BY));
		} else {
			countStr.append(HQL.substring(FROM));
		}
		return countStr.toString();
	}

	/**
	 * @author wangbo (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPageAmount(java.lang.String)
	 */
	private int findByPageAmountReturnPageModel(final String hql) {
		List list = this.getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						List result = session.createQuery(hql).list();
						return result;
					}
				});
		if (!list.isEmpty()) {
			return Integer.parseInt(list.get(0).toString());
		}
		return 0;
	}

	/**
	 * @author wangbo (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPageAmount(java.lang.String,
	 *      java.lang.String)
	 */
	private int findByPageAmountReturnPageModel(final String hql, final String value) {
		List list = this.getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						List result = session.createQuery(hql).setParameter(0,
								value).list();
						return result;
					}
				});
		if (!list.isEmpty()) {
			return Integer.parseInt(list.get(0).toString());
		}
		return 0;
	}

	/**
	 * @author wangbo (non-Javadoc)
	 * @see com.zmht.ers.core.dao.IBaseDAO#findByPageAmount(java.lang.String,
	 *      java.lang.Object[])
	 */
	private int findByPageAmountReturnPageModel(final String hql, final Object[] values) {
		List list = this.getHibernateTemplate().executeFind(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						for (int i = 0; i < values.length; i++) {
							query.setParameter(i, values[i]);
						}
						List result = query.list();
						return result;
					}
				});
		if (!list.isEmpty()) {
			return Integer.parseInt(list.get(0).toString());
		}
		return 0;
	}
	
	/**
	 * @author wangbo
	 * (non-Javadoc)
	 * @see com.superteam.deaf.core.dao.IBaseDAO#findBySQLReturnPageModel(java.lang.String, int, int)
	 */
	public PageModel findBySQLReturnPageModel(String sql, int currPage,
			int pageSize) {
		PageModel pageModel = new PageModel();
		pageModel.setResultAmount(this.findAmountBySql(sql));
		int pageAmount = (pageModel.getResultAmount()+pageSize-1)/pageSize;
		pageModel.setPageAmount(pageAmount==0?1:pageAmount);
		pageModel.setResultList(this.findBySql(sql,(currPage-1)*pageSize,pageSize));
		return pageModel;
	}
	public List findByHQL(String hql, String [] params, Object [] args) {
		
		return  this.getHibernateTemplate().findByNamedParam(hql, params, args);   
		
	}	
}

